<template>
  <!-- 搜索 -->
  <div class="search">
    <label>根据姓名搜索：</label>
    <el-select
      v-model="searchKey"
      filterable
      remote
      clearable
      placeholder="请输入姓名搜索"
      :remote-method="remoteMethod"
      @change="searchChange"
      :loading="searchLoading"
      @clear="clearSearchKey"
    >
      <el-option
        v-for="item in searchOptions"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
  </div>
  <!-- 添加按钮 -->
  <div class="add">
    <el-button type="primary" :icon="Plus" @click="addStu">添加项目</el-button>
  </div>

  <!-- 表格 -->
  <div class="table">
    <el-table
      :data="tableData"
      :border="true"
      style="width: 100%"
      v-loading="tableLoading"
    >
      <el-table-column prop="headimgurl" align="center" label="头像">
        <template v-slot="{ row }">
          <el-avatar
            size="large"
            shape="square"
            :src="row.headimgurl"
          ></el-avatar>
        </template>
      </el-table-column>
      <el-table-column prop="name" label="姓名" align="center" />
      <el-table-column prop="degree" label="学历" align="center" />
      <el-table-column prop="class" label="班级" align="center" />
      <el-table-column prop="productUrl" label="项目" align="center" />
      <el-table-column
        prop="cTime"
        width="200"
        label="创建时间"
        align="center"
      />
      <el-table-column label="操作" width="150" align="center">
        <template v-slot="{ row }">
          <el-button type="success" :icon="View" circle />
          <el-button type="primary" :icon="Edit" circle @click="edit(row)" />
          <el-button type="danger" :icon="Delete" circle @click="del(row)" />
        </template>
      </el-table-column>
    </el-table>
  </div>
  <!-- 分页 -->
  <div class="pageNation">
    <el-pagination
      background
      layout="prev, pager, next"
      :total="total"
      :page-size="pageSize"
      :current-page="currentPage"
      @current-change="pageChange"
    />
  </div>
  <!-- dialog弹窗组件 -->
  <qf-dialog
    :dialogFormData="dialogFormData"
    :title="dialogTitle"
    :visible="dialogVisible"
    @dialogCancel="dialogCancel"
    @validateSuccess="dialogFormValidateSuccess"
    @closed="close"
  >
    <template v-slot:upload>
      <el-upload
        class="avatar-uploader"
        method="post"
        action="/api/students/uploadStuAvatar"
        name="headimgurl"
        :show-file-list="false"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload"
      >
        <img v-if="imageUrl" :src="imageUrl" class="avatar" />
        <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
      </el-upload>
    </template>
  </qf-dialog>
</template>
<script setup>
import { ref, reactive } from "vue";
//引入图标
import { Plus, Delete, View, Edit } from "@element-plus/icons-vue";
import { onMounted } from "vue";
import * as api from "@/api/stu";
//引入dialog弹窗组件
import qfDialog from "@/components/dialog/index.vue";
//引入elementPlus消息提示
import { ElMessage, ElMessageBox } from "element-plus";
//搜索逻辑
// 搜索的可选择的下拉数据
let searchOptions = ref([]);
// 搜索的下拉选择的关键字
let searchKey = ref("");
//搜索加载动画
let searchLoading = ref(false);

//搜索两种情况：1.直接输入数据（searchKey.value为空，currentKeyword为搜索数据）2.下拉框选择数据（currentKeyword为空，searchKey.value为搜索数据）

// 搜索框输入后会触发的方法,参数是搜索的数据,这里负责呈现搜索的联想数据
let remoteMethod = async (currentKeyword) => {
  if (!currentKeyword) {
    return;
  }
  //开启加载动画
  searchLoading.value = true;
  try {
    let res = await api.searchStuListApi(currentKeyword, "");
    //给联想的下拉列表赋值
    let repeatDatas = res.data.data.map((item) => ({
      value: item.name,
    }));

    //去重操作
    let norepeatDatas = [];
    for (var i = 0; i < repeatDatas.length; i++) {
      let flag = true;
      for (var j = 0; j < norepeatDatas.length; j++) {
        if (repeatDatas[i].value === norepeatDatas[j].value) {
          flag = false;
          break;
        }
      }
      if (flag) {
        norepeatDatas.unshift(repeatDatas[i]);
      }
    }
    currentPage.value = 1;
    // console.log(repeatDatas);
    // console.log(norepeatDatas);
    searchOptions.value = norepeatDatas;
    //关闭加载动画
    searchLoading.value = false;
  } catch (e) {
    console.log(e);
    //关闭加载动画
    searchLoading.value = false;
  }
};
//清空关键字之后的方法
let clearSearchKey = () => {
  //初始化数据，让页码重新回到第一页
  currentPage.value = 1;
};
//用户选中了输入框的值后，负责更新表格数据
let searchChange = async (key, page = 1, count = 10) => {
  //开启加载动画
  tableLoading.value = true;
  searchOptions.value = [];
  try {
    let res = await api.searchStuListApi(searchKey.value, page, count);
    //给联想的下拉列表赋值
    tableData.value = res.data.data;
    //关闭加载动画
    tableLoading.value = false;

    //对搜索结果进行分页
    setPageNation(res.data.total);
  } catch (e) {
    console.log(e);
    //关闭加载动画
    tableLoading.value = false;
  }
};

//表格数据
let tableData = ref([]);
//表格加载动画
let tableLoading = ref(true);

//封装一个方法，专门用来获取表格数据
let getStulist = async (page, count, classes) => {
  //开启加载动画
  tableLoading.value = true;
  try {
    //请求表格数据
    let res = await api.getStuListApi(page, count, classes);

    //给表格列表赋值
    tableData.value = res.data.data;
    //关闭加载动画
    tableLoading.value = false;

    //设置分页器数量
    setPageNation(res.data.total);

    // console.log(res);
  } catch (e) {
    console.log(e);
    //关闭加载动画
    tableLoading.value = false;
  }
};

//分页器
let total = ref(1);
//每页显示的条数
let pageSize = ref(10);
//默认页面
let currentPage = ref(1);
//页面变更的时候
let pageChange = (inputCurrentPage) => {
  //动态变更页码
  currentPage.value = inputCurrentPage;
  //判断有没有搜索关键字，如果有，更新搜索的分页结果
  if (searchKey.value) {
    searchChange(null, inputCurrentPage);
  } else {
    //如果没有，拉取列表全部数据
    getStulist(inputCurrentPage);
  }
};
//专门修改分页器内容的方法
let setPageNation = (totalCount = 10, count = 10, currentPage = 1) => {
  total.value = totalCount;
  pageSize.value = count;
};

//dialog
//dialog标题
let dialogTitle = ref("添加学员信息");
//声明控制dialog显示和隐藏
let dialogVisible = ref(false);

let addStu = () => {
  dialogVisible.value = true;
  dialogTitle.value = "添加学员信息";
  imageUrl.value = "";
};

//dialogData数据源
let dialogFormData = reactive({
  name: {
    label: "姓名",
    value: "",
  },
  degree: {
    label: "学历",
    value: "",
  },
  class: {
    label: "班级",
    value: "",
  },
  age: {
    label: "年龄",
    value: "",
  },
  productUrl: {
    label: "项目地址",
    value: "",
  },
  city: {
    label: "城市",
    value: "",
  },

  description: {
    label: "描述",
    value: "",
  },
});
//dialog点击取消按钮触发的逻辑
let dialogCancel = () => {
  dialogVisible.value = false;
  console.log("已取消");
};
//dialog点击确定按钮，并且表单校验通过触发的逻辑
let dialogFormValidateSuccess = async (form) => {
  // console.log(dialogFormData);
  let message = "添加成功";
  let params = {
    headimgurl: "",
    name: dialogFormData.name.value,
    class: dialogFormData.class.value,
    age: dialogFormData.age.value,
    city: dialogFormData.city.value,
    degree: dialogFormData.degree.value,
    productUrl: dialogFormData.productUrl.value,
    description: dialogFormData.description.value,
  };
  try {
    //根据dialogTittle来区分要发送增加请求还是编辑请求
    let apiMethod = null;
    switch (dialogTitle.value) {
      case "添加学员信息":
        apiMethod = api.addStuApi;
        message = "添加成功";
        //删除sId属性
        params.sId ? delete params.sId : "";
        break;
      case "编辑学员信息":
        apiMethod = api.updateStuApi;
        //给params添加sId属性
        params.sId = sId.value;
        message = "修改成功";
    }
    //判断是否上传头像，如果上传了，那么携带到params中去
    params.headimgurl = headimgurl.value ? headimgurl.value : "";
    let res = await apiMethod(params);
    console.log(res);
    //添加成功：
    //1.提示添加成功
    ElMessage({
      message,
      type: "success",
    });
    //2.关掉dialog
    dialogVisible.value = false;
    //3.清空表单
    form.value.resetFields();
    //4.更新列表
    getStulist();

    // console.log(res);
  } catch (e) {
    ElMessage({
      message: e.toString(),
      type: "error",
    });
    console.log(e);
  }
};
//dialog关闭之后，要同步控制关闭属性的值
//这样做的目的是为了处理点击空白区域或者右上角叉叉的时候，造成的后续dialog不能弹出的情况
let close = () => {
  dialogVisible.value = false;
  //将数据清空
  let keys = Object.keys(dialogFormData);
  keys.forEach((key) => {
    dialogFormData[key].value = "";
  });
};
//编辑
//声明一个变量，存储sId,便于编辑的时候传递给后端
let sId = ref("");
let edit = (row) => {
  // console.log(row);
  //1.打开dialog
  dialogVisible.value = true;
  //2.修改标题
  dialogTitle.value = "编辑学员信息";
  //3.数据回显
  let keys = Object.keys(dialogFormData);
  keys.forEach((key) => {
    dialogFormData[key].value = row[key];
  });
  sId.value = row.sId;
  //更改全局的headimgurl这个字段，便于数据的传递
  headimgurl.value = row.headimgurl;
  // 图片回显
  imageUrl.value = row.headimgurl;
};

let del = (row) => {
  console.log(row);
  //获取当前数据的sId,传递给后天就可以了
  //1.交互：让用户确认是否删除
  ElMessageBox.confirm(
    "此操作将永久删除" + row.name + "，是否继续？",
    "删除提示",
    {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }
  )
    .then(async () => {
      //2.发请求，删除数据
      try {
        let res = await api.delStuApi(row.sId);
        ElMessage({
          type: "success",
          message: "删除成功",
        });
        currentPage.value = 1;
        getStulist();
      } catch (e) {
        ElMessage({
          type: "error",
          message: e.toString(),
        });
      }
    })
    .catch(() => {
      ElMessage({
        type: "warning",
        message: "已取消删除",
      });
    });
};

//上传图片
//一个保存上传地址的变量
let imageUrl = ref("");
//声明一个headimgUrl变量，用于将参数在表单dialog通过的时候，一并提交给后台
let headimgurl = ref("");
//上传成功的方法
let handleAvatarSuccess = (res, uploadFile) => {
  // console.log("res", res);
  // console.log("uploadFile.raw", uploadFile.raw);
  if (res.state) {
    ElMessage({
      type: "success",
      message: res.msg,
    });
    headimgurl.value = res.headimgurl;
    //上传成功后显示图片
    imageUrl.value = URL.createObjectURL(uploadFile.raw);
  } else {
    ElMessage({
      type: "error",
      message: res.msg,
    });
  }
};
//上传之前
let beforeAvatarUpload = (rawFile) => {
  //允许上传的文件类型
  let acceptType = ["image/jpeg", "image/png", "image/gif"];
  //判断当前上传的文件类型是否包含在上面的数组中
  let isAccept = acceptType.includes(rawFile.type);
  if (!isAccept) {
    ElMessage.error(
      "上传的文件类型只能是jpeg、gif或png!您当前长传的文件类型是" + rawFile.type
    );
    return false;
  } else if (rawFile.size / 1024 / 1024 > 1) {
    ElMessage.error("上传的文件大小不能超过1M");
    return false;
  }
  return true;
};

onMounted(() => {
  getStulist();
});
</script>
<script>
export default {
  meta: {
    title: "xyxmgl",
    name: "学员项目管理",
    routeName: "stuProduct",
    icon: "icon-shangpinguanli",
  },
};
</script>
<style scoped>
.search,
.add,
.table {
  margin: 15px 0;
}
.pageNation {
  text-align: center;
}
.el-pagination {
  justify-content: center;
}
.avatar-uploader .avatar {
  width: 130px;
  height: 125px;
  display: block;
}
</style>
